package dji.ux.ext.panel.camera;

import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.Group;

import java.util.ArrayList;
import java.util.List;

import dji.common.bus.UXSDKEventBus;
import dji.common.camera.CameraVideoStreamSource;
import dji.common.camera.SettingsDefinitions;
import dji.common.camera.ThermalMeasurementMode;
import dji.common.error.DJIError;
import dji.common.util.CommonCallbacks;
import dji.thirdparty.io.reactivex.android.schedulers.AndroidSchedulers;
import dji.ux.beta.R;
import dji.ux.beta.base.ConstraintLayoutWidget;
import dji.ux.beta.base.DJISDKModel;
import dji.ux.beta.base.uxsdkkeys.ObservableInMemoryKeyedStore;
import dji.ux.ext.base.UXEEvents;
import dji.ux.ext.base.view.SelectedOptionPanel;


/**
 * 适配h20/h20T相机的基本功能切换
 */
class CameraH20TPanel extends ConstraintLayoutWidget {
    private Button btnMode;
    private Button btnThermalZoom;
    private Button btnThermalMode;
    private Button btnTemperature;
    private TextView tvMode;
    private Group groupThermal;

    private CameraH20TModel widgetModel;

    private Handler uiHandle = new Handler();
    private CommonCallbacks.CompletionCallbackWith<CameraVideoStreamSource> cameraSourceCallback = new CommonCallbacks.CompletionCallbackWith<CameraVideoStreamSource>() {
        @Override
        public void onSuccess(CameraVideoStreamSource cameraVideoStreamSource) {
            uiHandle.post(() -> {
                String text = "镜头/" + CameraUtil.getVideoSourceName(cameraVideoStreamSource);
                btnMode.setText(text);
                tvMode.setText(CameraUtil.getVideoSourceName(cameraVideoStreamSource));
                if (cameraVideoStreamSource == CameraVideoStreamSource.INFRARED_THERMAL) {
                    groupThermal.setVisibility(VISIBLE);
                    UXSDKEventBus.getInstance().post(UXEEvents.CameraZoomVisibility.GONE);
                    updateThermalModeText();
                    updateThermalZoomText();
                } else if (cameraVideoStreamSource == CameraVideoStreamSource.WIDE) {
                    groupThermal.setVisibility(GONE);
                    UXSDKEventBus.getInstance().post(UXEEvents.CameraZoomVisibility.GONE);
                } else if (cameraVideoStreamSource == CameraVideoStreamSource.ZOOM) {
                    groupThermal.setVisibility(GONE);
                    UXSDKEventBus.getInstance().post(UXEEvents.CameraZoomVisibility.SHOW);
                } else {
                    groupThermal.setVisibility(GONE);
                    UXSDKEventBus.getInstance().post(UXEEvents.CameraZoomVisibility.GONE);
                }
                btnTemperature.setVisibility(GONE);
            });

        }

        @Override
        public void onFailure(DJIError djiError) {
            Log.e("UXESDK", "CameraVideoStreamSource callback failed:" + djiError.getDescription());
        }
    };

    public CameraH20TPanel(@NonNull Context context) {
        super(context);
    }

    public CameraH20TPanel(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public CameraH20TPanel(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void initView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        View view = inflate(context, R.layout.ext_panel_camera_h20t, this);

        btnMode = view.findViewById(R.id.btn_mode);
        tvMode = view.findViewById(R.id.tv_mode);
        btnThermalMode = view.findViewById(R.id.btn_thermal_mode);
        btnThermalZoom = view.findViewById(R.id.btn_thermal_zoom);
        btnTemperature = view.findViewById(R.id.btn_temperature_mode);
        groupThermal = view.findViewById(R.id.group_thermal);

        btnMode.setOnClickListener(this::showModeView);
        btnThermalMode.setOnClickListener(this::showThermalModeView);
        btnTemperature.setOnClickListener(this::showTemperatureModeView);
        btnThermalZoom.setOnClickListener(view1 -> widgetModel.setThermalDigitalZoom(CameraUtil.getTextToZoom(btnThermalZoom.getText().toString()), djiError -> uiHandle.post(CameraH20TPanel.this::updateThermalZoomText)));

        setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        if (!isInEditMode()) {
            widgetModel = new CameraH20TModel(DJISDKModel.getInstance(),
                    ObservableInMemoryKeyedStore.getInstance());
        }


    }

    void onRemoteMode(UXEEvents.RemoteCameraMode mode) {
        switch (mode) {
            case MSX:
                return;
            case VISUAL_ONLY:
                btnMode.setText("镜头/变焦");
                tvMode.setText("变焦");
                onModeSelected(2);
                break;
            case THERMAL_ONLY:
                btnMode.setText("镜头/红外");
                tvMode.setText("红外");
                onModeSelected(0);
                onThermalModeSelected(1);
                break;
            case PIP:
                btnMode.setText("镜头/红外");
                tvMode.setText("红外");
                onModeSelected(0);
                onThermalModeSelected(0);
                break;
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (!isInEditMode()) {
            widgetModel.setup();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        if (!isInEditMode()) {
            widgetModel.cleanup();
        }
        super.onDetachedFromWindow();
    }

    @Override
    protected void reactToModelChanges() {
        addReaction(widgetModel.getProductConnection()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(this::isProductConnected));
    }

    @NonNull
    @Override
    public String getIdealDimensionRatioString() {
        return null;
    }

    /**
     * auto show/hide widget when product connecting status changed
     *
     * @param isConnected is Product connected
     */
    private void isProductConnected(Boolean isConnected) {
        if (isConnected != null && isConnected) {
            if (widgetModel.isH20TCamera()) {
                setVisibility(VISIBLE);
                widgetModel.getH20TCameraSource(cameraSourceCallback);
            } else {
                setVisibility(GONE);
            }
        } else {
            setVisibility(GONE);
        }
    }

    /**
     * 相机模式弹窗
     *
     * @param view view
     */
    private void showModeView(View view) {
        PopupWindow popupWindow = new PopupWindow();
        SelectedOptionPanel panel = new SelectedOptionPanel(getContext());
        panel.setCallback((index, result) -> {
            UXSDKEventBus.getInstance().post(UXEEvents.ThermalMeasurementMode.NONE);
            UXSDKEventBus.getInstance().post(new UXEEvents.MeterAreaText("", false));

            String text = "镜头/" + result;
            btnMode.setText(text);
            tvMode.setText(result);
            onModeSelected(index);
            popupWindow.dismiss();
        });

        panel.setCurrentText(((Button) view).getText().toString().trim());

        List<String> data = new ArrayList<>();
        data.add("红外");
        data.add("变焦");
        data.add("广角");
        panel.setData(data);

        popupWindow.setContentView(panel);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setWidth(view.getMeasuredWidth());
        popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        popupWindow.showAsDropDown(view, 0, 0);
    }

    /**
     * 红外模式下的显示模式弹窗
     *
     * @param view view
     */
    private void showThermalModeView(View view) {
        PopupWindow popupWindow = new PopupWindow();
        SelectedOptionPanel panel = new SelectedOptionPanel(getContext());
        panel.setCallback((index, result) -> {
            onThermalModeSelected(index);
            popupWindow.dismiss();

        });

        panel.setCurrentText(((Button) view).getText().toString().trim());

        List<String> data = new ArrayList<>();
        data.add("分屏");
        data.add("红外");
        panel.setData(data);

        popupWindow.setContentView(panel);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setWidth(view.getMeasuredWidth());
        popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        popupWindow.showAsDropDown(view, 0, 0);
    }

    private void onModeSelected(int index) {
        if (index == 0) {
            groupThermal.setVisibility(VISIBLE);
        } else {
            groupThermal.setVisibility(GONE);
        }

        widgetModel.setH20TCameraSource(getVideoSourceFromIndex(index), djiError -> {
            if (djiError == null) {
                if (index == 0) {//红外
                    updateThermalModeText();
                    updateThermalZoomText();
                }
                if (index == 1) {//变焦
                    UXSDKEventBus.getInstance().post(UXEEvents.CameraZoomVisibility.SHOW);
                } else {
                    UXSDKEventBus.getInstance().post(UXEEvents.CameraZoomVisibility.GONE);
                }
            } else {
                Log.e("UXESDK", "setH20TCameraSource failed:" + djiError.getDescription());
            }
        });
    }

    /**
     * 显示红外镜头-红外模式下的测温模式
     * @param view view
     */
    private void showTemperatureModeView(View view) {
        PopupWindow popupWindow = new PopupWindow();
        SelectedOptionPanel panel = new SelectedOptionPanel(getContext());
        panel.setCallback((index, result) -> {
            widgetModel.setThermalMeasurementMode(CameraUtil.getMeasureModeFromIndex(index), djiError -> {
                if (djiError == null) {
                    updateMeasurementModeText();
                }
            });
            popupWindow.dismiss();
        });

        panel.setCurrentText(((Button) view).getText().toString().trim());
        List<String> meterModeList = new ArrayList<>();
        meterModeList.add("关闭");
        meterModeList.add("区域测温");
        meterModeList.add("指点测温");
        panel.setData(meterModeList);

        popupWindow.setContentView(panel);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setWidth(view.getMeasuredWidth());
        popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        popupWindow.showAsDropDown(view, 0, 0);
    }


    private void updateMeasurementModeText() {
        widgetModel.getThermalMeasurementMode(new CommonCallbacks.CompletionCallbackWith<ThermalMeasurementMode>() {
            @Override
            public void onSuccess(ThermalMeasurementMode thermalMeasurementMode) {
                uiHandle.post(() -> {
                    String text = CameraUtil.getMeasurementModeName(thermalMeasurementMode);
                    switch (text) {
                        case "关闭":
                            text = "测温/关闭";
                            UXSDKEventBus.getInstance().post(UXEEvents.ThermalMeasurementMode.NONE);
                            UXSDKEventBus.getInstance().post(new UXEEvents.MeterAreaText("", false));
                            break;
                        case "区域测温":
                            UXSDKEventBus.getInstance().post(UXEEvents.ThermalMeasurementMode.THERMAL_AREA_METER);
                            break;
                        case "指点测温":
                            UXSDKEventBus.getInstance().post(new UXEEvents.MeterAreaText("", false));
                            UXSDKEventBus.getInstance().post(UXEEvents.ThermalMeasurementMode.THERMAL_SPOT_METER);
                            break;
                    }
                    btnTemperature.setText(text);
                });
            }

            @Override
            public void onFailure(DJIError djiError) {

            }
        });
    }

    private void updateThermalModeText() {
        widgetModel.getDisplayMode(new CommonCallbacks.CompletionCallbackWith<SettingsDefinitions.DisplayMode>() {
            @Override
            public void onSuccess(SettingsDefinitions.DisplayMode displayMode) {
                uiHandle.post(() -> {
                    String text = CameraUtil.getDisplayModeName(displayMode);
                    if (text.equals("红外")){
                        btnTemperature.setVisibility(VISIBLE);
                        updateMeasurementModeText();
                    }else {
                        btnTemperature.setVisibility(GONE);
                        UXSDKEventBus.getInstance().post(UXEEvents.ThermalMeasurementMode.NONE);
                    }
                    text = "模式/" + text;
                    btnThermalMode.setText(text);

                });
            }

            @Override
            public void onFailure(DJIError djiError) {
                Log.e("UXESDK", "updateThermalModeText error:" + djiError.getDescription());

            }
        });
    }

    private void updateThermalZoomText() {
        widgetModel.getThermalDigitalZoom(new CommonCallbacks.CompletionCallbackWith<SettingsDefinitions.ThermalDigitalZoomFactor>() {
            @Override
            public void onSuccess(SettingsDefinitions.ThermalDigitalZoomFactor thermalDigitalZoomFactor) {
                uiHandle.post(() -> btnThermalZoom.setText(CameraUtil.getZoomToText(thermalDigitalZoomFactor)));
            }

            @Override
            public void onFailure(DJIError djiError) {
                Log.e("UXESDK", "updateThermalZoomText error:" + djiError.getDescription());

            }
        });
    }

    private void onThermalModeSelected(int index) {
        widgetModel.setDisplayMode(getDisplayModeFromIndex(index), djiError -> {
            if (djiError != null) {
                Log.e("UXESDK", "setDisplayMode err:" + djiError.getDescription());
            } else {
                if (index == 0)
                    widgetModel.setPIPPosition();
                updateThermalModeText();
            }
        });
    }


    private CameraVideoStreamSource getVideoSourceFromIndex(int index) {
        switch (index) {
            case 0:
                return CameraVideoStreamSource.INFRARED_THERMAL;
            case 1:
                return CameraVideoStreamSource.ZOOM;
            case 2:
                return CameraVideoStreamSource.WIDE;
        }

        return CameraVideoStreamSource.UNKNOWN;
    }

    private SettingsDefinitions.DisplayMode getDisplayModeFromIndex(int index) {
        switch (index) {
            case 0:
                return SettingsDefinitions.DisplayMode.PIP;
            case 1:
                return SettingsDefinitions.DisplayMode.THERMAL_ONLY;
        }

        return SettingsDefinitions.DisplayMode.PIP;
    }
}
